﻿#include "stdafx.h"
#include "RectMatch.h"
#include <stdio.h>
#include <math.h>

CRectMatch::CRectMatch(int x, int y)
{
	centerX = x;
	centerY = y;
}

void CRectMatch::UpDate(list<SOptImg>&alarmImg)
{
	int size = 0;
	size = tempRects.size();
	if (size == 0)
	{
		//printf("size=0\n");
		list<SRectPic>::iterator first = rectsATM.begin();
		list<SRectPic>::iterator last = rectsATM.end();
		while (first != last)
		{
			if (first->flag)
			{
				first->count += 1;
				first->flag = false;
			}
			first++;
		}
	}
	else
	{
		list<SRectPic>::iterator first = tempRects.begin();
		list<SRectPic>::iterator last = tempRects.end();
		while (first != last)
		{
			rectsATM.push_back(*first);
			first++;
		}
		tempRects.clear();
	}
	list<SRectPic>::iterator first = rectsATM.begin();
	list<SRectPic>::iterator last = rectsATM.end();
	while (first != last)
	{
		if (first->flag)
			first->count++;
		else
			first->flag = true;
		first++;
	}
	//删除元素
	last = rectsATM.end();
	first = rectsATM.begin();

	while (first != last)
	{
		if (first->count >= 4)
		{
			if (!first->bSend)
			{
				SOptImg opt;
				opt.optRect.x = first->optPic.optRect.x;
				opt.optRect.y = first->optPic.optRect.y;
				opt.optRect.width = first->optPic.optRect.width;
				opt.optRect.height = first->optPic.optRect.height;
				opt.img = cvCloneImage(first->optPic.img);
				opt.time = first->optPic.time;
				alarmImg.push_back(opt);
			}
			cvReleaseImage(&(first->optPic.img));
			first = rectsATM.erase(first);
		}
		else
		{
			first++;
		}
	}
}
int CRectMatch::match(list<CvRect>&vR, IplImage *pImg, time_t time, list<
		SOptImg>&alarmImg)
{
	if (vR.size() > 0)
	{
		list<CvRect> buff;//临时保存
		list<CvRect>::iterator ite = vR.end();
		list<CvRect>::iterator itb = vR.begin();

		while (itb != ite)
		{
			int count = 0;
			list<SRectPic>::iterator first = rectsATM.begin();
			list<SRectPic>::iterator last = rectsATM.end();
			while (first != last)
			{
				if (compare(first->backRect, *itb))
				{
					//printf("YES.....the same u gotta it.....\n");
					count++;
					first->backRect.x = itb->x;
					first->backRect.y = itb->y;
					first->backRect.width = itb->width;
					first->backRect.height = itb->height;
					first->count = 0;
					first->flag = false;
					if (!first->bSend)
					{
						int r = getOptRect(first->optPic.optRect, *itb);
						switch (r)
						{
						case 0:
							break;
						case 1:
						{
							first->optPic.optRect.x = itb->x;
							first->optPic.optRect.y = itb->y;
							first->optPic.optRect.width = itb->width;
							first->optPic.optRect.height = itb->height;

							cvReleaseImage(&(first->optPic.img));
							first->optPic.img = cvCloneImage(pImg);
							first->optPic.time = time;
							break;
						}
						case 2:
						{
							SOptImg opt;
							opt.optRect.x = itb->x;
							opt.optRect.y = itb->y;
							opt.optRect.width = itb->width;
							opt.optRect.height = itb->height;
							opt.img = cvCloneImage(pImg);
							opt.time = time;
							first->bSend = true;
							alarmImg.push_back(opt);
						}
						default:
							break;
						}
					}
					//////////delete vR[i];
					break;
				}
				else
				{
					//printf("NO ...IT's diffrence.....\n");
				}
				first++;
			}
			if (count == 0)
			{
				printf("NO ...IT's diffrence.....\n");
				SRectPic atm;
				atm.backRect.x = itb->x;
				atm.backRect.y = itb->y;
				atm.backRect.width = itb->width;
				atm.backRect.height = itb->height;
				atm.count = 0;
				atm.flag = false;
				atm.bSend = false;

				atm.optPic.optRect.x = itb->x;
				atm.optPic.optRect.y = itb->y;
				atm.optPic.optRect.width = itb->width;
				atm.optPic.optRect.height = itb->height;
				atm.optPic.time = time;
				atm.optPic.img = cvCloneImage(pImg);

				tempRects.push_back(atm);
			}
			itb++;
		}
	}
	UpDate(alarmImg);
	return 0;
}
void CRectMatch::print()
{
	list<SRectPic>::iterator first = rectsATM.begin();
	list<SRectPic>::iterator last = rectsATM.end();
	int i = 0;
	while (first != last)
	{
		printf("%d:	p:x=%d", i, first->backRect.x);
		printf("  p:y=%d", first->backRect.y);
		printf("  p:width=%d", first->backRect.width);
		printf("  p:height=%d-------->%d\n", first->backRect.height,
				first->count);
		first++;
		i++;
	}
}
bool CRectMatch::compare(CvRect &rect1, CvRect &rect2)
{
	int x1 = rect1.x;
	int y1 = rect1.y;
	int w1 = rect1.width;
	int h1 = rect1.height;

	int x2 = rect2.x;
	int y2 = rect2.y;
	int w2 = rect2.width;
	int h2 = rect2.height;

	float tw = w1 > w2 ? ((w2 * 1.0) / w1) : ((w1 * 1.0) / w2);
	bool bw = (int) (tw + 0.3) < 1;

	float th = h1 > h2 ? ((h2 * 1.0) / h1) : ((h1 * 1.0) / h2);
	bool bh = (int) (th + 0.3) < 1;

	if (bw || bh)
	{
		return false;
	}
	else
	{
		int xt = x1 > x2 ? x1 : x2;
		int yt = y1 > y2 ? y1 : y2;
		int xb = (x1 + w1) > (x2 + w2) ? x2 + w2 : x1 + w1;
		int yb = (y1 + h1) > (y2 + h2) ? y2 + h2 : y1 + h1;

		int area = (xb - xt) * (yb - yt);
		float area1 = w1 * h1 * 1.0;
		float area2 = w2 * h2 * 1.0;

		if ((int) (area / area1 + 0.4) >= 1)
			return true;
		else if ((int) (area / area2 + 0.4) >= 1)
			return true;
		else
			return false;
	}

}
int CRectMatch::getOptRect(CvRect &rect1, CvRect &rect2)
{
	int R1x = rect1.x + rect1.width / 2;
	int R1y = rect1.y + rect1.height / 2;
	int x = abs(R1x - centerX);
	int y = abs(R1y - centerY);
	int dist1 = (int) sqrt(double(x * x + y * y));
	if (dist1 <= 10)
	{
		return 2;
	}
	int R2x = rect2.x + rect2.width / 2;
	int R2y = rect2.y + rect2.height / 2;

	x = abs(R2x - centerX);
	y = abs(R2y - centerY);
	int dist2 = (int) sqrt(double(x * x + y * y));

	if (dist2 < dist1)
		return 1;
	else
		return 0;
}
